/*
 * EBFV1_loadEdges.cpp
 *
 *  Created on: 16/09/2012
 *      Author: rogsoares
 */
#include "EBFV1_preprocessor.h"

void loadCij(ifstream &fid, TMesh *pTMesh_data){
	PetscPrintf(PETSC_COMM_WORLD,"Loading Edges...\t");
	string str[10];
	const int dim = 3;
	int j, i = 0;
	int edgeIDs[2];
	bool hasRC=false;
	GED_list global_list;		// List of edges Lists

	fid >> str[0];
	getline(fid,str[0],'\n');
	for (i=0; i<pTMesh_data->getNumDomains(); i++){
		getline(fid,str[0],'\n');
		EdgeData* edata;
		ED_list edgeList;					// list for domain dom vertices
		while ( 1 ){
			edata = new EdgeData;
			fid>>str[0];
			if (str[0] == "end") break;
			edata->flag = atoi(str[0].c_str());			// flag
			for (j=1; j<=dim+3; j++){
				fid >> str[j];
			}
			edata->numRC = atoi(str[1].c_str());				// number of remote copies
			edgeIDs[0] = atoi(str[2].c_str());		// ID0
			edgeIDs[1] = atoi(str[3].c_str());		// ID1

			if (edata->numRC>0){
				hasRC = true;
			}
			if (edgeIDs[0]>edgeIDs[1]){
				std::swap(edgeIDs[0],edgeIDs[1]);
			}

			edata->Cij = new double[dim];
			for (j=0; j<dim; j++){
				edata->Cij[j] = strtod(str[j+4].c_str(),0);
			}
			// Cij vector norm
			edata->Cij_norm = norm_L2(edata->Cij,dim);
			edata->ID_0 = edgeIDs[0];
			edata->ID_1 = edgeIDs[1];
			edata->versor = new double[dim];
			edata->vel_new = new double[dim];
			edata->vel_old = new double[dim];
			for (int j=0; j<dim; j++){
				edata->vel_new[j] = .0;
				edata->vel_old[j] = .0;
			}

			edgeList.push_back(edata);
		}
		getline(fid,str[0],'\n');
		global_list.push_back(edgeList);
	}
	transferEdgeDataFromListToMatrix(pTMesh_data,global_list);
	PetscPrintf(PETSC_COMM_WORLD,"done\n");
}

/*
 * It's intended to work with an matrix and not a list.
 */
void transferEdgeDataFromListToMatrix(TMesh *pTMesh_data, GED_list &globalList){
	int i = 0;
	GED_list::iterator GED_iter = globalList.begin();
	for (;GED_iter != globalList.end(); GED_iter++){
		ED_list edlist = *GED_iter;
		int nrows = (int)edlist.size();
		pTMesh_data->edge_list[i].allocateMemory(nrows,1);

		int j = 0;
		ED_list::iterator edlist_iter = edlist.begin();
		for (;edlist_iter != edlist.end(); edlist_iter++){
			pTMesh_data->edge_list[i].setValue(j++,0,*edlist_iter);
		}
		i++;
	}
	globalList.clear();
}

// for debug purposes only
void printEdgesData(TMesh *pTMesh_data){
	int nrows, ncols;
	int ndom = pTMesh_data->getNumDomains();
	for (int i=0; i<ndom; i++){
		pTMesh_data->edge_list[i].getSize(nrows,ncols);
		for (int j=0; j<nrows; j++){
			EdgeData* edata = pTMesh_data->edge_list[i].getValue(j,0);
			cout << setprecision(5) << scientific;
			cout << edata->ID_0 << "\t";
			cout << edata->ID_1 << "\t";
			cout << edata->flag  << "\t";
			cout << edata->numRC << "\t";
			cout << edata->Cij[0] << "\t";
			cout << edata->Cij[1] << "\t";
			cout << edata->Cij[2] << "\t";
			cout << endl;
		}
	}
}

